package com.gadberry.utility.algorithm;

import java.util.List;

import com.gadberry.utility.expression.Argument;
import com.gadberry.utility.expression.Expression;
import com.gadberry.utility.expression.Function;
import com.gadberry.utility.expression.InvalidArgumentsException;
import com.gadberry.utility.expression.OperatorSet;

/**
 * Used to retrieve a value associated with a variable name.
 * 
 * @author Peter Lager
 *
 */
public class VarFunction extends Function {

	public VarFunction(Expression expression) {
		super(expression);
	}

	@Override
	public Argument resolve(Algorithm algor) throws InvalidVariableUseException {
		if(algor != null){
			Argument arg = algor.getVariable(getArgument(0).toString());
			if(arg == null)
				throw new InvalidVariableUseException("Uninitialised variable " + getArgument(0).toString());
			return arg;
		}
		else
			return null; // can't have variables without an algorithm
	}

	@Override
	protected void checkArgs(List<Argument> args)
	throws InvalidArgumentsException, InvalidVariableUseException {
		if (args.size() != 1) {
			throw new InvalidArgumentsException(
					"$'arg' requires a single argument.  Wrong number of arguments provided.");
		}
		int n = -1;

		for (Argument arg : args) { 
			n++;
			if(arg.isNull()) {
				throw new InvalidArgumentsException(
						"$ fuction cannot accept null arguments.  The argument provided is null.");
			} else if (!arg.isLiteral()) {
				String delim = arg.toString();
				if(OperatorSet.hasOperator(delim)){
					// If we don't surround variables with parenthesises then the operator is picked up
					// as an argument. If this happens just move on.
					throw new InvalidArgumentsException("Invalid arguments for the $ function");					
				}
				else {
					// We have not surrounded the variable name with single quotes i.e.
					// $name instead of $'name'
					String name = arg.getObject().toString().replaceAll("'", "");
					int pos = name.indexOf(" ");
					if(pos > 0)
						name = name.substring(0, pos);				
					throw new InvalidVariableUseException("This syntax: $" + arg.toString() + " is invalid!  Use $'" + name +"' ");
				}
			}
		}
	}

}
